import time
from datetime import datetime

from hikaru.meta import KubernetesException
from hikaru.model.rel_1_26 import PersistentVolumeClaim
from kubernetes import client
from robusta.api import ActionParams, ExecutionBaseEvent, Finding, FindingType, MarkdownBlock, action


class VolumeSnapshotParams(ActionParams):
    """
    :var name: name of the PersistentVolumeClaim to backup
    :var namespace: namespace of the PersistentVolumeClaim to backup
    :example name: some_pvc_name
    """

    name: str
    namespace: str = "default"


@action
def create_pvc_snapshot(event: ExecutionBaseEvent, params: VolumeSnapshotParams):
    """
    Backup a PersistentVolume by creating a VolumeSnapshot
    """
    try:
        pvc = PersistentVolumeClaim().read(name=params.name, namespace=params.namespace)
    except KubernetesException:
        event.add_finding(
            Finding(
                title=f"Error creating VolumeSnapshot for {params.name}",
                aggregation_key="VolumeSnapshotError",
                finding_type=FindingType.ISSUE,
                failure=True,
            )
        )
        event.add_enrichment(
            [
                MarkdownBlock(
                    f"Backup failed because PersistentVolumeClaim {params.name} in namespace {params.namespace} doesn't exist"
                )
            ]
        )
        return

    formatted_date = datetime.now().strftime("%m-%d-%y")
    snapshot_name = f"{params.name}-backup-{formatted_date}-{int(time.time())}"

    # both the kubernetes client and hikaru don't have proper support for snapshots in the autogenerated classes
    # hence the workarounds here
    # see https://stackoverflow.com/questions/67157702/can-i-take-a-volume-snapshot-with-the-k8s-python-client
    snapshot_body = {
        "apiVersion": "snapshot.storage.k8s.io/v1beta1",
        "kind": "VolumeSnapshot",
        "metadata": {"name": snapshot_name, "namespace": pvc.metadata.namespace},
        "spec": {
            # "volumeSnapshotClassName": "example-snapshot-class",
            "source": {"persistentVolumeClaimName": pvc.metadata.name}
        },
    }
    crd_api = client.CustomObjectsApi()
    crd_api.create_namespaced_custom_object(
        group="snapshot.storage.k8s.io",
        version="v1beta1",
        namespace=pvc.metadata.namespace,
        plural="volumesnapshots",
        body=snapshot_body,
    )
    finding = Finding(
        title=f"Created VolumeSnapshot {snapshot_name}",
        aggregation_key="VolumeSnapshot",
        finding_type=FindingType.REPORT,
        failure=False,
    )
    finding.add_enrichment([MarkdownBlock("Successfully created snapshot")])
    event.add_finding(finding)
